//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.vere.rpc.server;

import com.vere.rpc.model.ServiceItem;
import com.vere.rpc.msg.CallMessage;
import com.vere.rpc.util.ObjectUtil;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class RemoteServer {
    public RemoteServer() {
    }

    public static void start(int port) {
        ServerSocketChannel channel = null;

        try {
            System.out.println("VereRPC Startup Successfull， Listening Port :  " + port + "  ......");
            channel = ServerSocketChannel.open();
            channel.configureBlocking(false);
            channel.socket().bind(new InetSocketAddress(port));
            RegistryService.loadResources();
            startListen(channel);
        } catch (Exception var11) {
            var11.printStackTrace();
        } finally {
            try {
                channel.close();
            } catch (IOException var10) {
                var10.printStackTrace();
            }

        }

    }

    private static void startListen(ServerSocketChannel serverSocketChannel) {
        try {
            Selector selector = Selector.open();
            serverSocketChannel.register(selector, 16);

            while(selector.select() > 0) {
                for(Iterator iterator = selector.selectedKeys().iterator(); iterator.hasNext(); iterator.remove()) {
                    SelectionKey selectionKey = (SelectionKey)iterator.next();
                    if (selectionKey.isValid() && selectionKey.isAcceptable()) {
                        doAcceptable(serverSocketChannel, selector);
                    } else if (selectionKey.isValid() && selectionKey.isReadable()) {
                        doReadable(serverSocketChannel, selector, selectionKey);
                    } else if (selectionKey.isValid()) {
                        selectionKey.isWritable();
                    }
                }
            }
        } catch (Exception var4) {
            var4.printStackTrace();
        }

    }

    private static void doAcceptable(ServerSocketChannel serverSocketChannel, Selector selector) {
        SocketChannel socketChannel = null;

        try {
            socketChannel = serverSocketChannel.accept();
            if (socketChannel == null) {
                return;
            }

            socketChannel.configureBlocking(false);
            socketChannel.register(selector, 1);
        } catch (Exception var4) {
            var4.printStackTrace();
        }

    }

    private static void doReadable(ServerSocketChannel serverSocketChannel, Selector selector, SelectionKey selectionKey) {
        SocketChannel socketChannel = (SocketChannel)selectionKey.channel();

        try {
            Object obj = ObjectUtil.receiveObject(socketChannel);
            if (obj == null) {
                return;
            }

            CallMessage callMessage = (CallMessage)obj;
            if (CallMessage.INVOKE == callMessage.getAction()) {
                invoke(callMessage, socketChannel);
            } else if (CallMessage.CLOSE == callMessage.getAction()) {
                ObjectUtil.close(socketChannel);
            }
        } catch (Exception var6) {
            var6.printStackTrace();
        }

    }

    private static void invoke(CallMessage callMessage, SocketChannel socketChannel) {
        try {
            ServiceItem serviceItem = RegistryService.getService(callMessage.getServiceInterface());
            Class clazz = Class.forName(serviceItem.getServiceClass());
            String clientId = socketChannel.socket().getRemoteSocketAddress().toString();
            Object objectInstance = CacheData.get(clientId);
            if (objectInstance == null) {
                objectInstance = clazz.newInstance();
                CacheData.put(clientId, objectInstance);
            }

            Method method = clazz.getDeclaredMethod(callMessage.getMethodName(), callMessage.getTypes());
            Object returnObj = method.invoke(objectInstance, callMessage.getObjects());
            ObjectUtil.sendObject(socketChannel, returnObj);
        } catch (Exception var8) {
            var8.printStackTrace();
        }

    }
}
